type Char   native;  // rune (int32)
type String native;  // string

export function =: &(Char,Char) => Bool
    native '=Char';

export function Char?:
    &(Number) => Maybe[Char]
    native 'chr';

export function Seq:
    &(String) => Seq[Char]
    native 'Seq from String';

export function List:
    &(String) => List[Char]
    &(str) => str.{Seq}.{List};

export function = :
    &(String,String) => Bool
    native '=String';

export function  < :
    &(String,String) => Bool
    native '<String';

export function <> :
    &(String,String) => Ordering
    native '<>String';

export function String:
    &(List[Char]) => String
    native 'String from List';

export function String:
    &(Char) => String
    native 'String from Char';

export function String:
    &(Bool) => String
    native 'String from Bool';

/// encodes string into UTF-8 byte sequence
export function encode:
    &(String) => Bytes
    native 'encode-utf8';

/// decodes string from UTF-8 byte sequence
export function decode:
    &(Bytes) => Maybe[String]
    native 'decode-utf8';

/// decodes string from UTF-8 byte sequence (outputs \uFFFD on error)
export function decode!:
    &(Bytes) => String
    native 'force-decode-utf8';

export function quote:
    &(String) => String
    native 'quote';

export function unquote:
    &(String) => Maybe[String]
    native 'unquote';

// TODO: parse-int
export function parse-float:
    &(String) => Maybe[NormalFloat]
    native 'parse-float';

export function length:
    &(String) => Number
    native 'str-length';

export function shift:
    &(String) => Maybe[(Char,String)]
    native 'str-shift';

export function shift-prefix:
    &(String,String) => Maybe[String]
    native 'str-shift-prefix';

export function contains:
    &(String,String) => Bool
    native 'str-contains';

export function contains:
    &(String,Char) => Bool
    &(s,char) =>
        ({ Seq s } some &(c) => (c = char));

export function concat:
    &(List[String]) => String
    native 'str-concat';

export function split:
    &(String,String) => Seq[String]
    native 'str-split';

export function join:
    &(Seq[String],String) => String
    native 'str-join';

export function join:
    &(Seq[String],Char) => String
    &(seq,char) => seq.{join({String [char]})};

export function join:
    &(List[String],String) => String
    &(arr,sep) => arr.{Seq}.{join(sep)};

export function join:
    &(List[String],Char) => String
    &(arr,char) => arr.{Seq}.{join(char)};

export function trim:
    &(String,Char) => String
    native 'trim';

export function trim-left:
    &(String,Char) => String
    native 'trim-left';

export function trim-right:
    &(String,Char) => String
    native 'trim-right';

export function trim-prefix:
    &(String,String) => String
    native 'trim-prefix';

export function trim-suffix:
    &(String,String) => String
    native 'trim-suffix';

export function has-prefix:
    &(String,String) => Bool
    native 'has-prefix';

export function has-suffix:
    &(String,String) => Bool
    native 'has-suffix';
